package com.orm;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import com.always.ClassUtil;
import com.annotation.table.Column;
import com.annotation.table.Id;
import com.annotation.table.Table;
import com.annotation.table.Transient;
import com.exception.table.IdException;

import lombok.Getter;
import lombok.ToString;
import lombok.extern.log4j.Log4j2;

@Getter
@ToString
@Log4j2
public class TableInfo {
	/**
	 * 操作的类类型
	 */
	private Class<?> classType;
	/**
	 * 表名
	 */
	private String table;
	/**
	 * 主键名
	 */
	private String id;
	/**
	 * 主键的类型
	 */
	private String idType;
	/**
	 * 属性名
	 */
	private String fieldId;
	/**
	 * 列名
	 */
	private List<String> column;
	/**
	 * 属性名
	 */
	private List<String> field;
	/**
	 * 忽略映射的属性
	 */
	private List<String> ignore;

	/**
	 * 有参构造方法
	 * 
	 * @param classType
	 *            指定操作的类类型
	 */
	public TableInfo(Class<?> classType) {
		this.classType = classType;
		this.column = new ArrayList<>();
		this.field = new ArrayList<>();
		this.ignore = new ArrayList<>();
		/**
		 * 根据类类型,获取表名,主键,列信息
		 */
		// 获取类上的table注解
		Table tableAnnotation = classType.getDeclaredAnnotation(Table.class);
		// 获取表名
		if (tableAnnotation != null) {
			this.table = tableAnnotation.value();
		} else {
			this.table = classType.getSimpleName();
		}
		// 获取全部属性
		Field[] fields = classType.getDeclaredFields();
		// 定义id标识
		boolean id = false;
		// 遍历属性
		for (Field field : fields) {
			// 获取属性的@Transient注解
			Transient transientAnnotation = field.getDeclaredAnnotation(Transient.class);
			// 获取属性的修饰符
			boolean isStatic = Modifier.isStatic(field.getModifiers());
			// 判断属性是静态的或者有@Transient注解,则不进行映射
			if (isStatic || null != transientAnnotation) {
				// 忽略该属性的映射
				ignore.add(field.getName());
				continue;
			}
			// 获取属性的@Id注解
			Id idAnnotation = field.getDeclaredAnnotation(Id.class);
			if (null != idAnnotation) {
				// 主键
				id = !id;
				this.fieldId = field.getName();
				this.idType = ClassUtil.classType(field.getType());
				if (idAnnotation.value().trim().equals("")) {
					this.id = field.getName();
				} else {
					this.id = idAnnotation.value();
				}
				continue;
			}
			// 获取属性上的@Column注解
			Column columnAnnotation = field.getDeclaredAnnotation(Column.class);
			this.field.add(field.getName());
			if (columnAnnotation != null) {
				this.column.add(columnAnnotation.value());
			} else {
				this.column.add(field.getName());
			}
		}
		// 处理异常
		if(null == this.id || !id){
			throw new IdException("主键异常 ....");
		}
		log.info(this.toString());
	}
}
